#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/file.h>
#include <termios.h>
#include <time.h>
#include <errno.h>
#include <ctype.h>  

#define JSON_RESPONSE "Content-Type: application/json;charset=UTF-8\r\n\r\n"
#define SERIAL_PORT "/dev/ttyUSB0"
#define LOCK_FILE "/tmp/zigbee_lock"

// 函数声明
int init_serial();
int acquire_lock();
int release_lock();
int send_zigbee_command(const char *cmd, char *response, int max_len);
void urldecode(char *dst, const char *src);
void log_debug(const char *message);  // 添加调试日志

// 调试日志函数
void log_debug(const char *message) {
    FILE *log = fopen("/tmp/zigbee_debug.log", "a");
    if (log) {
        fprintf(log, "[%ld] %s\n", time(NULL), message);
        fclose(log);
    }
}

int main() {
    char *method = getenv("REQUEST_METHOD");
    char *query_string = getenv("QUERY_STRING");
    
    log_debug("CGI脚本启动");
    
    if (!method || strcmp(method, "GET") != 0) {
        printf(JSON_RESPONSE);
        printf("{\"status\":\"error\",\"msg\":\"只支持GET请求\"}");
        return 1;
    }
    
    if (!query_string) {
        printf(JSON_RESPONSE);
        printf("{\"status\":\"error\",\"msg\":\"缺少查询参数\"}");
        return 1;
    }
    
    // 解析参数
    char device[32] = {0};
    char action[32] = {0};
    char value[32] = {0};
    
    char decoded_query[256] = {0};
    urldecode(decoded_query, query_string);
    
    char *token = strtok(decoded_query, "&");
    while (token) {
        char *eq = strchr(token, '=');
        if (eq) {
            *eq = '\0';
            char *name = token;
            char *val = eq + 1;
            
            if (strcmp(name, "device") == 0) strncpy(device, val, 31);
            else if (strcmp(name, "action") == 0) strncpy(action, val, 31);
            else if (strcmp(name, "value") == 0) strncpy(value, val, 31);
        }
        token = strtok(NULL, "&");
    }
    
    // 记录接收到的参数
    char log_msg[256];
    snprintf(log_msg, sizeof(log_msg), "收到命令: device=%s, action=%s, value=%s", device, action, value);
    log_debug(log_msg);
    
    printf(JSON_RESPONSE);
    
    if (strlen(device) == 0 || strlen(action) == 0) {
        printf("{\"status\":\"error\",\"msg\":\"缺少必要参数\"}");
        return 1;
    }
    
    // 设备控制逻辑
    if (strcmp(device, "led") == 0) {
        if (strcmp(action, "on") == 0) {
            // 尝试发送JSON格式命令
            if (send_zigbee_command("{\"device\":\"led\",\"cmd\":\"on\"}", NULL, 0) == 0) {
                printf("{\"status\":\"success\",\"msg\":\"LED已开启\"}");
                log_debug("LED开启成功");
            } else {
                printf("{\"status\":\"error\",\"msg\":\"LED开启失败\"}");
                log_debug("LED开启失败");
            }
        }
        else if (strcmp(action, "off") == 0) {
            if (send_zigbee_command("{\"device\":\"led\",\"cmd\":\"off\"}", NULL, 0) == 0) {
                printf("{\"status\":\"success\",\"msg\":\"LED已关闭\"}");
                log_debug("LED关闭成功");
            } else {
                printf("{\"status\":\"error\",\"msg\":\"LED关闭失败\"}");
                log_debug("LED关闭失败");
            }
        }
        else if (strcmp(action, "brightness") == 0 && strlen(value) > 0) {
            char cmd[100];
            snprintf(cmd, sizeof(cmd), "{\"device\":\"led\",\"cmd\":\"brightness\",\"value\":%s}", value);
            if (send_zigbee_command(cmd, NULL, 0) == 0) {
                printf("{\"status\":\"success\",\"msg\":\"亮度设置成功\",\"value\":%s}", value);
                log_debug("LED亮度设置成功");
            } else {
                printf("{\"status\":\"error\",\"msg\":\"亮度设置失败\"}");
                log_debug("LED亮度设置失败");
            }
        }
        else {
            printf("{\"status\":\"error\",\"msg\":\"不支持的LED操作\"}");
        }
    }
    else if (strcmp(device, "fan") == 0) {
        if (strcmp(action, "on") == 0) {
            if (send_zigbee_command("{\"device\":\"fan\",\"cmd\":\"on\"}", NULL, 0) == 0) {
                printf("{\"status\":\"success\",\"msg\":\"风扇已开启\"}");
                log_debug("风扇开启成功");
            } else {
                printf("{\"status\":\"error\",\"msg\":\"风扇开启失败\"}");
                log_debug("风扇开启失败");
            }
        }
        else if (strcmp(action, "close") == 0) {
            if (send_zigbee_command("{\"device\":\"fan\",\"cmd\":\"off\"}", NULL, 0) == 0) {
                printf("{\"status\":\"success\",\"msg\":\"风扇已关闭\"}");
                log_debug("风扇关闭成功");
            } else {
                printf("{\"status\":\"error\",\"msg\":\"风扇关闭失败\"}");
                log_debug("风扇关闭失败");
            }
        }
        else if (strcmp(action, "speed") == 0 && strlen(value) > 0) {
            char cmd[100];
            snprintf(cmd, sizeof(cmd), "{\"device\":\"fan\",\"cmd\":\"speed\",\"value\":%s}", value);
            if (send_zigbee_command(cmd, NULL, 0) == 0) {
                printf("{\"status\":\"success\",\"msg\":\"风速设置成功\",\"value\":%s}", value);
                log_debug("风扇速度设置成功");
            } else {
                printf("{\"status\":\"error\",\"msg\":\"风速设置失败\"}");
                log_debug("风扇速度设置失败");
            }
        }
        else {
            printf("{\"status\":\"error\",\"msg\":\"不supported的风扇操作\"}");
        }
    }
    else if (strcmp(device, "sensor") == 0) {
        if (strcmp(action, "read") == 0) {
            char response[256] = {0};
            if (send_zigbee_command("{\"device\":\"sensor\",\"cmd\":\"read\"}", response, sizeof(response)) == 0 && strlen(response) > 0) {
                log_debug("收到传感器响应");
                // 直接返回接收到的JSON响应
                printf("%s", response);
            } else {
                // 模拟数据（备用）
                log_debug("使用模拟传感器数据");
                time_t ts = time(NULL);
                printf("{\"status\":\"success\",\"temperature\":24.5,\"humidity\":55.5,\"timestamp\":%ld}", ts);
            }
        }
        else {
            printf("{\"status\":\"error\",\"msg\":\"不支持的传感器操作\"}");
        }
    }
    else if (strcmp(device, "camera") == 0) {
        // 摄像头控制（模拟）
        log_debug("摄像头命令（模拟）");
        if (strcmp(action, "stream_start") == 0) {
            printf("{\"status\":\"success\",\"msg\":\"视频流已启动\"}");
        }
        else if (strcmp(action, "record_start") == 0) {
            printf("{\"status\":\"success\",\"msg\":\"录像已开始\"}");
        }
        else if (strcmp(action, "record_stop") == 0) {
            printf("{\"status\":\"success\",\"msg\":\"录像已停止\"}");
        }
        else {
            printf("{\"status\":\"error\",\"msg\":\"不支持的摄像头操作\"}");
        }
    }
    else {
        printf("{\"status\":\"error\",\"msg\":\"不支持的设备类型\"}");
    }
    
    log_debug("CGI脚本结束");
    return 0;
}

int init_serial() {
    log_debug("尝试打开串口");
    
    int fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_SYNC);
    if (fd < 0) {
        char err_msg[100];
        snprintf(err_msg, sizeof(err_msg), "打开串口失败: %s", strerror(errno));
        log_debug(err_msg);
        return -1;
    }
    
    struct termios tty;
    if (tcgetattr(fd, &tty) != 0) {
        log_debug("获取串口属性失败");
        close(fd);
        return -1;
    }
    
    cfsetospeed(&tty, B9600);
    cfsetispeed(&tty, B9600);
    
    tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;
    tty.c_iflag &= ~IGNBRK;
    tty.c_lflag = 0;
    tty.c_oflag = 0;
    tty.c_cc[VMIN] = 1;
    tty.c_cc[VTIME] = 5;
    
    tty.c_iflag &= ~(IXON | IXOFF | IXANY);
    tty.c_cflag |= (CLOCAL | CREAD);
    tty.c_cflag &= ~(PARENB | PARODD);
    tty.c_cflag &= ~CSTOPB;
    tty.c_cflag &= ~CRTSCTS;
    
    if (tcsetattr(fd, TCSANOW, &tty) != 0) {
        log_debug("设置串口属性失败");
        close(fd);
        return -1;
    }
    
    log_debug("串口初始化成功");
    return fd;
}

int acquire_lock() {
    int lock_fd = open(LOCK_FILE, O_CREAT | O_RDWR, 0666);
    if (lock_fd < 0) {
        log_debug("创建锁文件失败");
        return -1;
    }
    
    if (flock(lock_fd, LOCK_EX | LOCK_NB) != 0) {
        log_debug("串口被其他进程占用");
        close(lock_fd);
        return -1;
    }
    
    return lock_fd;
}

int release_lock() {
    int lock_fd = open(LOCK_FILE, O_RDWR);
    if (lock_fd < 0) return -1;
    
    flock(lock_fd, LOCK_UN);
    close(lock_fd);
    return 0;
}

int send_zigbee_command(const char *cmd, char *response, int max_len) {
    log_debug("开始发送Zigbee命令");
    
    int lock_fd = acquire_lock();
    if (lock_fd < 0) {
        log_debug("获取锁失败");
        return -1;
    }
    
    int serial_fd = init_serial();
    if (serial_fd < 0) {
        log_debug("串口初始化失败");
        release_lock();
        return -1;
    }
    
    // 记录发送的命令
    char log_cmd[256];
    snprintf(log_cmd, sizeof(log_cmd), "发送命令: %s", cmd);
    log_debug(log_cmd);
    
    // 发送命令
    char full_cmd[256];
    snprintf(full_cmd, sizeof(full_cmd), "%s\n", cmd);  // 添加换行符
    ssize_t written = write(serial_fd, full_cmd, strlen(full_cmd));
    
    if (written != (ssize_t)strlen(full_cmd)) {
        log_debug("命令发送不完整");
        close(serial_fd);
        release_lock();
        return -1;
    }
    
    tcdrain(serial_fd);
    log_debug("命令发送完成");
    
    // 读取响应（如果需要）
    if (response && max_len > 0) {
        usleep(500000); // 等待500ms让设备响应
        
        // 清空响应缓冲区
        memset(response, 0, max_len);
        
        int total_read = 0;
        int n;
        
        // 尝试读取多次，直到没有数据或缓冲区满
        while (total_read < max_len - 1) {
            n = read(serial_fd, response + total_read, max_len - 1 - total_read);
            if (n > 0) {
                total_read += n;
                // 如果读取到的数据包含换行符，认为响应结束
                if (memchr(response, '\n', total_read) != NULL) {
                    break;
                }
            } else if (n == 0) {
                // 没有更多数据
                break;
            } else {
                // 读取错误
                if (errno != EAGAIN && errno != EWOULDBLOCK) {
                    break;
                }
            }
            usleep(100000); // 每次读取后等待100ms
        }
        
        if (total_read > 0) {
            response[total_read] = '\0';
            // 去除可能的换行符
            if (total_read > 0 && response[total_read-1] == '\n') {
                response[total_read-1] = '\0';
            }
            
            char log_resp[300];
            snprintf(log_resp, sizeof(log_resp), "收到响应: %s", response);
            log_debug(log_resp);
        } else {
            log_debug("没有收到响应");
        }
    }
    
    close(serial_fd);
    release_lock();
    log_debug("Zigbee命令处理完成");
    return 0;
}

void urldecode(char *dst, const char *src) {
    char a, b;
    while (*src) {
        if ((*src == '%') && (a = src[1]) && (b = src[2]) && isxdigit(a) && isxdigit(b)) {
            if (a >= 'a') a -= 'a'-'A';
            if (a >= 'A') a -= ('A' - 10);
            else a -= '0';
            if (b >= 'a') b -= 'a'-'A';
            if (b >= 'A') b -= ('A' - 10);
            else b -= '0';
            *dst++ = 16*a+b;
            src += 3;
        } else if (*src == '+') {
            *dst++ = ' ';
            src++;
        } else {
            *dst++ = *src++;
        }
    }
    *dst = '\0';
}
